#include "FileHandler.h"

FileHandler* FileHandler::instance = NULL;

FileHandler::FileHandler() {
	this->nDocs = 0;
	this->nTerminos = 0;
}

FileHandler* FileHandler::getInstance() {
	if (instance == NULL)
		instance = new FileHandler();
	return instance;
}

FileHandler::~FileHandler() {
	if (instance != NULL)
		delete instance;
}

unsigned int FileHandler::getNTerminos() {
	return nTerminos;
}

void FileHandler::setNterminos(unsigned int nTerminos) {
	this->nTerminos = nTerminos;
}

unsigned int FileHandler::getNDocs() {
	return nDocs;
}

void FileHandler::setNDocs(unsigned int nTerminos) {
	this->nTerminos = nTerminos;
}

ArchivoAuxiliar* FileHandler::merge(ArchivoAuxiliar* file, vector<RegistroAuxiliar*> *buffer) {
	stringstream filename(stringstream::in | stringstream::out);
	filename << "IndiceInvertido";
	filename << ++this->nDocs;

	if (file == NULL) {
		file = new ArchivoAuxiliar(filename.str().c_str());
		for (unsigned int i = 0; i < buffer->size(); i++) {
			RegistroAuxiliar* reg = buffer->at(i);
			file->write(*reg);
			nTerminos++;
		}
		file->flush();
		return file;
	}

	ArchivoAuxiliar *res = new ArchivoAuxiliar(filename.str().c_str());
	file->clear();
	file->seekg(0, ios::beg);

	vector<RegistroAuxiliar*>::iterator it = buffer->begin();
	RegistroAuxiliar *r1 = new RegistroAuxiliar();
	file->read(r1);

	while (it != buffer->end()) {
		RegistroAuxiliar *r2 = *it;
		if (!r1 || r2->getTermino() < r1->getTermino()) {
			res->write(*r2);
			it++;
		}

		else if (r1->getTermino() < r2->getTermino()) {
			res->write(*r1);
			delete (r1);
			r1 = new RegistroAuxiliar();
			if (file->read(r1) == RES_EOF) {
				delete (r1);
				r1 = NULL;
			}
		}

		else {
			RegistroAuxiliar* r3 = new RegistroAuxiliar();
			r3->setTermino(r1->getTermino());
			vector<uint32_t>* nroDocs = r1->getNroDocs();
			vector<uint16_t>* frecuencias = r1->getFrecuencias();

			for (unsigned int i = 0; i < r2->getNroDocs()->size(); i++) {
				nroDocs->push_back(r2->getNroDocs()->at(i));
				frecuencias->push_back(r2->getFrecuencias()->at(i));
			}

			for (unsigned int j = 0; j < nroDocs->size(); j++) {
				r3->agregarDocumento(nroDocs->at(j));
				r3->agregarFrecuencia(frecuencias->at(j));
			}

			it++;
			delete (r1);
			r1 = new RegistroAuxiliar();

			if (file->read(r1) == RES_EOF) {
				delete (r1);
				r1 = NULL;
			}

			res->write(*r3);
		}

		nTerminos++;
	}

	if (r1)
		res->write(*r1);

	delete (r1);
	r1 = new RegistroAuxiliar();

	while (file->read(r1) != RES_EOF) {
		res->write(*r1);
		delete (r1);
		r1 = new RegistroAuxiliar();
		nTerminos++;
	}

	delete (r1);
	delete (file);

	res->flush();

	stringstream previousName(stringstream::in | stringstream::out);
	previousName << "IndiceInvertido";
	previousName << this->nDocs - 1;
	remove(previousName.str().c_str());

	return res;
}
